package com.nutiteq.mapper.forms;

import java.io.IOException;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.game.Sprite;

import com.nutiteq.MapComponent;
import com.nutiteq.components.Place;
import com.nutiteq.components.PlaceIcon;
import com.nutiteq.components.WgsBoundingBox;
import com.nutiteq.components.WgsPoint;
import com.nutiteq.mapper.MapScreen;
import com.nutiteq.mapper.Mapper;

public class BoundingBoxForm extends Form implements CommandListener {

  public static final Command SET_BOUNDING_BOX = new Command("Set bounding box", Command.ITEM, 0);

  private final MapComponent mapDisplay;

  private static final Place[] BOUNDING_PLACES = new Place[2];

  private Command back;
  private Command setBBox;

  private TextField minLat;
  private TextField minLon;
  private TextField maxLat;
  private TextField maxLon;

  private PlaceIcon bboxMin;
  private PlaceIcon bboxMax;

  private WgsBoundingBox previous;

  public BoundingBoxForm(final MapComponent mapDisplay) {
    super("Bounding box");
    this.mapDisplay = mapDisplay;

    previous = mapDisplay.getBoundingBox();

    minLon = new TextField("Min point lon in decimal degrees", Double.toString(previous.getWgsMin()
        .getLon()), 9, TextField.ANY);
    minLat = new TextField("Min point lat in decimal degrees", Double.toString(previous.getWgsMin()
        .getLat()), 9, TextField.ANY);
    maxLon = new TextField("Max point lon in decimal degrees", Double.toString(previous.getWgsMax()
        .getLon()), 9, TextField.ANY);
    maxLat = new TextField("Max point lat in decimal degrees", Double.toString(previous.getWgsMax()
        .getLat()), 9, TextField.ANY);

    append(minLat);
    append(minLon);
    append(maxLat);
    append(maxLon);

    back = new Command("Back", Command.BACK, 0);
    setBBox = new Command("Set BBox", Command.OK, 0);

    addCommand(back);
    addCommand(setBBox);
    
    setCommandListener(this);

    try {
      final Image bBoxImages = Image.createImage("/bbox.png");
      bboxMin = new PlaceIcon(Image.createImage(bBoxImages, 0, 0, 10, 10, Sprite.TRANS_NONE), 0, 10);
      bboxMax = new PlaceIcon(Image.createImage(bBoxImages, 10, 0, 10, 10, Sprite.TRANS_NONE), 10,
          0);
    } catch (IOException ignore) {
    }
  }

  public void commandAction(final Command cmd, final Displayable d) {
    Display.getDisplay(Mapper.instance).setCurrent(MapScreen.instance);

    if (cmd == setBBox) {
      if (BOUNDING_PLACES[0] != null) {
        mapDisplay.removePlaces(BOUNDING_PLACES);
      }

      final WgsPoint newMin = new WgsPoint(ensureNumber(minLon.getString(), previous.getWgsMin()
          .getLon()), ensureNumber(minLat.getString(), previous.getWgsMin().getLat()));
      final WgsPoint newMax = new WgsPoint(ensureNumber(maxLon.getString(), previous.getWgsMax()
          .getLon()), ensureNumber(maxLat.getString(), previous.getWgsMax().getLat()));
      BOUNDING_PLACES[0] = createBoundingPlace(newMin, bboxMin, "Min");
      BOUNDING_PLACES[1] = createBoundingPlace(newMax, bboxMax, "Max");

      mapDisplay.addPlaces(BOUNDING_PLACES);
      mapDisplay.setBoundingBox(new WgsBoundingBox(newMin, newMax));
    }
  }

  private Place createBoundingPlace(final WgsPoint point, final PlaceIcon icon, final String label) {
    return new Place(0, label, icon, point);
  }

  private double ensureNumber(final String number, final double defaultValue) {
    try {
      return Double.parseDouble(number);
    } catch (NumberFormatException e) {
      return defaultValue;
    }
  }
}
